#!/usr/bin/env python3
"""
量化数据获取系统
主程序入口点
"""

import sys
import os
import argparse
import logging
from pathlib import Path

# 添加src目录到Python路径
sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'src'))

from src.utils.config import get_settings, ensure_data_dirs
from src.utils.logger import get_logger
from src.utils.validators import DataValidator, ValidationError
from src.data_fetcher import DataFetcher, DataFetchError
from src.data_storage import DataStorage
from src.schedule_manager import ScheduleManager
# GUI模式已弃用，使用Web UI替代
# from src.main_window import main as gui_main

# 设置日志
logger = get_logger("Main")


def validate_environment():
    """验证运行环境"""
    try:
        # 检查配置文件
        settings = get_settings()

        # 验证配置
        errors = DataValidator.validate_config(settings)
        if errors:
            logger.error("配置验证失败:")
            for error in errors:
                logger.error(f"  - {error}")
            return False

        # 确保数据目录存在
        ensure_data_dirs()

        # 检查必要的依赖
        required_modules = [
            'pandas', 'numpy', 'requests',
            'Flask', 'Flask-SocketIO', 'plotly'
        ]

        missing_modules = []
        for module in required_modules:
            try:
                if module == 'Flask-SocketIO':
                    __import__('flask_socketio')
                else:
                    __import__(module.lower())
            except ImportError:
                missing_modules.append(module)

        if missing_modules:
            logger.error(f"缺少必要的依赖模块: {', '.join(missing_modules)}")
            logger.error("请运行: pip install -r requirements.txt")
            return False

        return True

    except Exception as e:
        logger.error(f"环境验证失败: {e}")
        return False


def fetch_single_symbol(symbol: str, interval: str = '1d', output_dir: str = None):
    """获取单个股票数据"""
    try:
        if not DataValidator.validate_symbol(symbol):
            logger.error(f"无效的股票代码: {symbol}")
            return False

        if not DataValidator.validate_interval(interval):
            logger.error(f"无效的数据间隔: {interval}")
            return False

        logger.info(f"开始获取 {symbol} 的数据 ({interval})")

        fetcher = DataFetcher()
        storage = DataStorage()

        # 获取数据
        data = fetcher.fetch_full_history(symbol, interval)

        if data.empty:
            logger.error(f"未获取到 {symbol} 的数据")
            return False

        # 保存数据
        if output_dir:
            # 自定义输出目录
            output_path = Path(output_dir)
            output_path.mkdir(parents=True, exist_ok=True)
            file_path = output_path / f"{symbol}_{interval}.csv"
            data.to_csv(file_path, index=False, encoding='utf-8')
            logger.info(f"数据已保存到: {file_path}")
        else:
            # 使用默认存储
            storage.save_data(symbol, data, interval)
            logger.info(f"数据已保存到默认位置")

        logger.info(f"成功获取 {symbol} 的数据: {len(data)} 条记录")
        return True

    except Exception as e:
        logger.error(f"获取 {symbol} 数据失败: {e}")
        return False


def fetch_multiple_symbols(symbols: list, interval: str = '1d', output_dir: str = None):
    """批量获取多个股票数据"""
    try:
        if not symbols:
            logger.error("股票代码列表为空")
            return False

        logger.info(f"开始批量获取 {len(symbols)} 个股票的数据 ({interval})")

        fetcher = DataFetcher()
        storage = DataStorage()

        successful_count = 0
        failed_count = 0

        for i, symbol in enumerate(symbols):
            logger.info(f"处理 {symbol} ({i+1}/{len(symbols)})")

            try:
                # 获取数据
                data = fetcher.fetch_full_history(symbol, interval)

                if not data.empty:
                    # 保存数据
                    if output_dir:
                        output_path = Path(output_dir)
                        output_path.mkdir(parents=True, exist_ok=True)
                        file_path = output_path / f"{symbol}_{interval}.csv"
                        data.to_csv(file_path, index=False, encoding='utf-8')
                    else:
                        storage.save_data(symbol, data, interval)

                    successful_count += 1
                    logger.info(f"成功获取 {symbol} 数据: {len(data)} 条记录")
                else:
                    failed_count += 1
                    logger.warning(f"未获取到 {symbol} 的数据")

            except Exception as e:
                failed_count += 1
                logger.error(f"获取 {symbol} 数据失败: {e}")

        logger.info(f"批量获取完成: 成功 {successful_count}, 失败 {failed_count}")
        return successful_count > 0

    except Exception as e:
        logger.error(f"批量获取数据失败: {e}")
        return False


def run_scheduler():
    """运行定时任务管理器"""
    try:
        logger.info("启动定时任务管理器")

        schedule_manager = ScheduleManager()
        schedule_manager.start()

        # 从配置加载任务
        schedule_manager.load_tasks_from_config()

        logger.info("定时任务管理器已启动，按 Ctrl+C 停止")

        try:
            while True:
                import time
                time.sleep(1)
        except KeyboardInterrupt:
            logger.info("正在停止定时任务管理器...")
            schedule_manager.stop()
            logger.info("定时任务管理器已停止")

    except Exception as e:
        logger.error(f"运行定时任务管理器失败: {e}")


def show_system_info():
    """显示系统信息"""
    try:
        settings = get_settings()
        dirs = ensure_data_dirs()

        print("=== 量化数据获取系统 ===")
        print(f"版本: {settings['system'].get('version', 'Unknown')}")
        print(f"数据源: {settings['system'].get('data_source', 'Unknown')}")
        print(f"数据目录: {dirs['data_dir']}")
        print(f"日志目录: {dirs['log_dir']}")
        print(f"日志级别: {settings['system'].get('log_level', 'INFO')}")
        print()

        print("=== 支持的数据间隔 ===")
        for interval in settings['data_fetch'].get('supported_intervals', []):
            print(f"  - {interval}")
        print()

        print("=== 默认配置 ===")
        print(f"默认间隔: {settings['data_fetch'].get('default_interval', '1d')}")
        print(f"最大重试次数: {settings['data_fetch'].get('max_retries', 3)}")
        print(f"请求延迟: {settings['data_fetch'].get('request_delay', 1.0)}秒")
        print()

        print("=== 预设股票代码 ===")
        favorites = settings['stock_symbols'].get('favorites', [])
        if favorites:
            for symbol in favorites:
                print(f"  - {symbol}")
        else:
            print("  (无预设股票代码)")
        print()

    except Exception as e:
        logger.error(f"显示系统信息失败: {e}")


def main():
    """主函数"""
    parser = argparse.ArgumentParser(description='量化数据获取系统')
    parser.add_argument('--mode', choices=['web', 'cli', 'scheduler', 'info'],
                       default='web', help='运行模式')
    parser.add_argument('--symbol', type=str, help='股票代码')
    parser.add_argument('--symbols', type=str, nargs='+', help='多个股票代码')
    parser.add_argument('--interval', type=str, default='1d',
                       choices=['1d', '1h', '30m', '15m', '5m'], help='数据间隔')
    parser.add_argument('--output', type=str, help='输出目录')
    parser.add_argument('--log-level', type=str, default='INFO',
                       choices=['DEBUG', 'INFO', 'WARNING', 'ERROR'], help='日志级别')

    args = parser.parse_args()

    # 设置日志级别
    import logging
    logging.getLogger().setLevel(getattr(logging, args.log_level.upper()))

    # 验证环境
    if not validate_environment():
        logger.error("环境验证失败，请检查配置和依赖")
        sys.exit(1)

    try:
        if args.mode == 'web':
            # 启动Web UI
            start_web_ui()

        elif args.mode == 'cli':
            # 命令行模式
            if args.symbol:
                # 单个股票
                success = fetch_single_symbol(args.symbol, args.interval, args.output)
                sys.exit(0 if success else 1)
            elif args.symbols:
                # 多个股票
                success = fetch_multiple_symbols(args.symbols, args.interval, args.output)
                sys.exit(0 if success else 1)
            else:
                logger.error("CLI模式需要指定 --symbol 或 --symbols")
                sys.exit(1)

        elif args.mode == 'scheduler':
            # 定时任务模式
            run_scheduler()

        elif args.mode == 'info':
            # 显示系统信息
            show_system_info()

    except KeyboardInterrupt:
        logger.info("程序被用户中断")
        sys.exit(0)
    except Exception as e:
        logger.error(f"程序运行失败: {e}")
        sys.exit(1)


def start_web_ui():
    """启动Web UI"""
    import webbrowser
    import threading
    import time

    print("\n" + "="*50)
    print("启动现代化Web UI界面")
    print("="*50)

    try:
        # 导入Flask应用
        import sys
        from pathlib import Path

        web_ui_path = Path(__file__).parent / 'web_ui'
        sys.path.insert(0, str(web_ui_path))

        from app import app, socketio, init_components

        # 初始化组件
        init_components()

        # 设置Flask应用为生产模式
        app.config['DEBUG'] = False

        print("✅ Web UI组件初始化成功")
        print("🌐 启动Web服务器...")
        print("📱 界面地址: http://127.0.0.1:5000")
        print("🎯 现代化K线图: http://127.0.0.1:5000/kline")
        print("\n💡 提示: 按 Ctrl+C 停止服务")

        # 延迟打开浏览器
        def open_browser():
            time.sleep(2)
            webbrowser.open('http://127.0.0.1:5000')

        browser_thread = threading.Thread(target=open_browser)
        browser_thread.daemon = True
        browser_thread.start()

        # 启动Flask应用
        socketio.run(app, debug=False, host='127.0.0.1', port=5000, use_reloader=False)

    except ImportError as e:
        print(f"❌ 导入Web UI模块失败: {e}")
        print("请确保已安装Flask: pip install Flask>=2.3.0 Flask-SocketIO>=5.3.0")
    except Exception as e:
        print(f"❌ 启动Web UI失败: {e}")
        logger.error(f"Web UI启动失败: {e}")


if __name__ == "__main__":
    main()